﻿using MsgManager;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;

namespace SampleServer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class ServerWindows : Window
    {
        private MessageManager manager; // We need MessageManager object to send messages and call other methods.

        private int server_port = 5000;

        public ServerWindows()
        {
            InitializeComponent();

            // Create manager in constructor with desirable name
            // It does not matter what name it is, it's just for you.
            manager = new MessageManager("server");

            // Set event handler for message manager
            manager.ClientConneted += manager_ClientConneted;
            manager.ClientDisconnected += manager_ClientDisconnected;
            manager.MessageSendSuccess += manager_MessageSendSuccess;
            manager.MessageSendFailed += manager_MessageSendFailed;
            manager.MessageReceived += manager_MessageReceived;
        }

        //----------------------- Form Events --------------------------//

        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            // Start server
            if (manager.Running) return;

            manager.StartServer(server_port);

            // Update UI
            btnStart.IsEnabled = false;
            btnStop.IsEnabled = true;
            Log("Server started");
        }

        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            // Stop server
            if (!manager.Running) return;

            manager.StopServer();

            // Update UI
            btnStart.IsEnabled = true;
            btnStop.IsEnabled = false;
            Log("Server stopped");
        }

        private void btnKickAll_Click(object sender, RoutedEventArgs e)
        {
            Log("All client kicked");

            manager.StopAllListening();
        }

        private void btnSendMessage_Click(object sender, RoutedEventArgs e)
        {
            // Get all client we are listed to from manager
            List<Client> clients = manager.ListenedClients;

            // Create sample message using type and some data/payload
            Message sampleMessage = new Message("example type", "example data");

            // Send this message to all connected clients
            foreach (Client client in clients)
            {
                manager.SendMessageAsync(client, sampleMessage);
            }

            Log("message send started");
        }

        //----------------- Message Manager Events --------------------//

        private void manager_MessageReceived(object sender, MessageReceivedArgs e)
        {
            Client client = e.Client;
            Message message = e.Message;

            Log(String.Format("{0}: message received - {1}", client.IP, message.MessageType));
        }

        private void manager_MessageSendFailed(object sender, MessageSendResultArgs e)
        {
            Log(String.Format("{0}: message send failed", e.Client.IP));
        }

        private void manager_MessageSendSuccess(object sender, MessageSendResultArgs e)
        {
            Log(String.Format("{0}: message send success", e.Client.IP));
        }

        private void manager_ClientDisconnected(object sender, ClientConnectedArgs e)
        {
            Client client = e.Client;
            Log(String.Format("{0}: client disconnected", client.IP));

            // Stop listening to client
            manager.StopListening(client);
        }

        private void manager_ClientConneted(object sender, ClientConnectedArgs e)
        {
            Client client = e.Client;
            Log(String.Format("{0}: Client connected", client.IP));

            // It is important to invoke action on UI, as it could be called from others thread
            // Because Message Manager works from asynchronously it is important to use invoker
            App.Current.Dispatcher.Invoke((Action)delegate
            {
                btnSendMsg.IsEnabled = true;
                btnKickAll.IsEnabled = true;
            });  

            // Start listen for messages from client
            manager.StartListening(client);
        }

        //---------------------- Helper ----------------------------//

        private void Log(string log)
        {
            App.Current.Dispatcher.Invoke((Action)delegate
            {
                txtLog.Text = log + Environment.NewLine + txtLog.Text;
            });      
        }

        private void Window_Closed_1(object sender, EventArgs e)
        {
            // When closing app make sure to stop server and stop listening for other clients
            // As it is done on other threads it would not be closed itself
            manager.StopServer();
            manager.StopAllListening();
        }
    }
}
